package org.infosec.lc.exercises.springAspect.annotations;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

/**
	文件名：AnnotationAspect.java
	作  者：林超
	时  间：2011-4-18上午09:32:34

	功能描述：@annotation表示标注了某个注解的所有方法。
	
	pom.xml	:
 * @param <T>
			
 */
@Aspect
public class AnnotationAspect {

	@Around("@annotation(t)")	//①后置增强切面
//	@AfterThrowing(pointcut="@annotation(t)",throwing="ex")
//	@AfterReturning(pointcut="@annotation(t)",returning="w")
	public Object needTestFun(ProceedingJoinPoint joinPoint,TestAnnotation t)throws Throwable{
//	public void needTestFun(JoinPoint joinPoint,TestAnnotation t,Exception ex){
		System.out.println("needTestFun() executed!");
		System.out.println(t.method());
//		System.out.println(w);
//		System.out.println(ex);
		System.out.println(t.desc());
		Object ret = null;
		
		try {
			/**
			 * java.lang.Object proceed() throws java.lang.Throwable：
			 * 			通过反射执行目标对象的连接点处的方法； 
 			 * java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable：
			 *			通过反射执行目标对象连接点处的方法，不过使用新的入参替换原来的入参。
			 */
			
//			Object[] o = joinPoint.getArgs();]
			ret = joinPoint.proceed();
			System.out.println(ret);	//执行原有的入参，所得结果
//			o = new Object[]{1,"d"};
//			System.out.println(joinPoint.proceed(o));	//执行新的入参，所得结果
		} catch (Throwable e) {
			//e.printStackTrace();
			
			
//			StackTraceElement[] stack = e.getStackTrace();
//			for(StackTraceElement s:stack){
//				System.out.println(s);
//			}
//			System.out.println(e.toString());
//			System.out.println("--------------------------");
//			for(String string:ExceptionUtils.getRootCauseStackTrace(e))
//				System.out.println(string);
//			
			System.out.println("出错！"); 
			
			throw e;
		}
		System.out.println("---------------------------------------------");
		return ret;
			
//		String clazz = joinPoint.getTarget().getClass().getName();
//		System.out.println(clazz);
//		System.out.println(joinPoint.getSignature().toLongString());
		
//		Class  test = Class.forName(clazz);  
		/**
		 * test.getDeclaredMethods();   ---->  不包括继承的方法。
		 * test.getMethods();			---->  包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口
		 */
		
//		Method m = test.getMethod(joinPoint.getSignature().getName(),int.class,String.class,Object[].class);
//		TestAnnotation name = m.getAnnotation(TestAnnotation.class); 
//    	
//    	System.out.println("操作名 : " + name.method());
//    	System.out.println("描述：" + name.desc());
		
//        Method[] method = test.getMethods();  
//       
//        //把被@AfterReturning利用到@TestAnnotation的全部方法保存到Set中去  
//        Set<Method> set = new HashSet<Method>();  
//        for(int i=0;i<method.length;i++)  
//        {  
//            boolean otherFlag = method[i].isAnnotationPresent(TestAnnotation.class);  
//            if(otherFlag) set.add(method[i]);  
//        }  
//        for(Method m: set)  
//        {  
//        	TestAnnotation name = m.getAnnotation(TestAnnotation.class); 
//        	
//        	System.out.println("操作名 : " + name.method());
//        	System.out.println("描述：" + name.desc());
//        }  
	
//        System.out.println("---------------------------------------------\n");
		
	}
}

